class GameController {

	static scaffold = true
	
	def cubeService
	
	def unitService
	
	def place = {
		def place = Place.get(params.id)
		log.debug "place = ${place}"
		
		def cubes = Cube.createCriteria().list {
			eq('place', place)
			order('z')
			order('y')
			order('x')
		}
		
		def unit = Unit.get(params.unit)
		
		def pathCubes = parsePathCubes(place, params.path)
		log.debug "pathCubes = ${pathCubes}"

		def fromCube = pathCubes ? pathCubes.first() : null
		def toCube = pathCubes ? pathCubes.last() : null
		def beforeToCube = pathCubes.size() > 1 ? pathCubes[(pathCubes.size() - 2)] : null
		
		def adjacentCubes = []
		def adjCubesDir = [:]
		if (toCube) adjacentCubes = cubeService.getAdjacentCubes(toCube)
		if (toCube) adjCubesDir = cubeService.getDirectionsByCubes(toCube)
		
		return [place:place, cubes:cubes, unit:unit, fromCube:fromCube, toCube:toCube, beforeToCube:beforeToCube, adjacentCubes:adjacentCubes, adjCubesDir:adjCubesDir, pathCubes:pathCubes]
	}
	
	List parsePathCubes(place, param) {
		def cubePathList = []
		if (param) cubePathList = param.split(',')
		log.debug "cubePathList = ${cubePathList}"
		
		return cubePathList.collect {
			def split = it.split('\\.')
			log.debug "split ${it} = ${split}" 
			return Cube.findWhere(place:place, x:split[0].toInteger(), y:split[1].toInteger(), z:split[2].toInteger())
		}
	}
	
	def selectUnit = {
		def unit = Unit.get(params.id)
		log.debug "select unit ${unit}"
		
		def place = Place.get(params.place)
		log.debug "place = ${place}"
		
		def path = Cube.findByPlaceAndUnit(place, unit).coords()
		
		redirect action:'place', id:place.id, params:[unit:unit.id, path:path]
	}
	
	def appendCubeForMove = {
		def cube = Cube.get(params.id)
		log.debug "append cube ${params.id} = ${cube} for move"
		
		def unit = Unit.get(params.unit)
		log.debug "select unit ${unit}"
		
		if (!unit)  throw new NullPointerException("select a unit at first, before trying to move it !")
		//if (!unit.cube)  throw new NullPointerException("unit ${unit} is not on a cube !")
		
		def place = cube.place
		
		def pathCubes = parsePathCubes(place, params.path)
		
		def lastCube = pathCubes.last()
		log.debug "last cube = ${lastCube}"
		
		def beforeLastCube = pathCubes.size() > 1 ? pathCubes[(pathCubes.size() - 2)] : null
		log.debug "before last cube = ${lastCube}"
		
		if (cube == beforeLastCube) {
			log.debug "step back"
			pathCubes.remove(lastCube)
		} else {
			log.debug "step forward"
			if (cubeService.isMoveOk(lastCube, cube)) {
				pathCubes.add(cube)
			} else {
				flash.error = "unit ${unit} is not allowed to move from ${lastCube} to ${cube} !"
			}
			
		}
		
		def path = pathCubes.collect{ it.coords() }.join(',')
		
		redirect action:'place', id:place.id, params:[unit:unit.id, path:path]
	}
	
	def moveUnit = {
		def unit = Unit.get(params.id)
		log.debug "select unit ${unit}"
		
		def place = Place.get(params.place)
		log.debug "place = ${place}"
		
		def pathCubes = parsePathCubes(place, params.path)
		
		unitService.move(unit, pathCubes)
		
		redirect action:'place', id:place.id
	}
	
}